package kubenates

import (
	"fmt"
	"github.com/bytedance/sonic/loader"
	"helm.sh/helm/v3/pkg/cli"
	"helm.sh/helm/v3/pkg/getter"
	"helm.sh/helm/v3/pkg/repo"
	"kube-store-operator/commons/logger"
	"os"
)

func add(entry *repo.Entry) error {
	settings := cli.New()

	repoFile := settings.RepositoryConfig

	// 加载仓库配置文件
	repositories, err := repo.LoadFile(repoFile)
	// 如果文件不存在
	if err != nil {
		// 创建一个新的仓库配置对象
		repositories = repo.NewFile()
	}

	// 检查要添加的仓库是否已存在
	if repositories.Has(entry.Name) {
		return fmt.Errorf("仓库 %s 已存在", entry.Name)
	}

	// 添加仓库信息到仓库配置
	repositories.Add(entry)

	// 保存更新后的仓库配置到文件
	if err = repositories.WriteFile(repoFile, 0644); err != nil {
		return fmt.Errorf("无法保存仓库配置文件：%s", err)
	}

	logger.Debugf("成功添加仓库地址：%s。", entry.Name)
	return nil
}
func list() ([]*repo.Entry, error) {
	settings := cli.New()

	// 加载仓库配置文件
	repositories, err := repo.LoadFile(settings.RepositoryConfig)
	if err != nil {
		return nil, fmt.Errorf("无法保存仓库配置文件：%s", err)
	}
	return repositories.Repositories, nil
}
func remove(repoName string) error {
	settings := cli.New()

	repoFile := settings.RepositoryConfig

	// 加载仓库配置文件
	repositories, err := repo.LoadFile(repoFile)
	if err != nil {
		return fmt.Errorf("无法加载仓库配置文件：%s", err)
	}

	// 检查要删除的仓库是否存在
	if !repositories.Has(repoName) {
		return fmt.Errorf("仓库 %s 不存在", repoName)
	}

	// 从仓库配置中删除仓库
	result := repositories.Remove(repoName)

	// 保存更新后的仓库配置到文件
	if err = repositories.WriteFile(repoFile, 0644); err != nil || !result {
		return fmt.Errorf("无法保存仓库配置文件：%s", err)
	}

	logger.Debugf("成功删除仓库地址: %s。", repoName)
	return nil
}
func update() (string, error) {
	settings := cli.New()
	// 加载仓库配置文件
	repositories, err := repo.LoadFile(settings.RepositoryConfig)
	if err != nil {
		return "", fmt.Errorf("无法加载仓库配置文件：%s", err)
	}

	// 遍历每个仓库
	for _, repoEntry := range repositories.Repositories {
		// 添加要检索的仓库
		chartRepository, err := repo.NewChartRepository(repoEntry, getter.All(settings))
		if err != nil {
			return "", fmt.Errorf("无法添加仓库：%s\n", err)
		}

		// 更新仓库索引信息
		if _, err := chartRepository.DownloadIndexFile(); err != nil {
			return "", fmt.Errorf("无法下载仓库索引：%s\n", err)
		}

		logger.Debugf("...Successfully got an update from the %s chart repository", repoEntry.Name)
	}

	return "Update Complete. ⎈Happy Helming!⎈", nil
}
func search(repoName string) ([]*ChartListResponse, error) {
	settings := cli.New()

	path := fmt.Sprintf("%s/%s-index.yaml", settings.RepositoryCache, repoName)
	// 加载 xxx-index.yaml 文件
	indexFile, err := repo.LoadIndexFile(path)
	if err != nil {
		return nil, fmt.Errorf("仓库 %s 不存在", repoName)
	}

	var chartList []*ChartListResponse

	// 遍历指定仓库的 Chart 信息
	for _, entry := range indexFile.Entries {
		// 将每个 Chart 的最新信息提取出来
		chart := &ChartListResponse{
			ChartName:    entry[0].Name,
			ChartVersion: entry[0].Version,
			AppVersion:   entry[0].AppVersion,
			Description:  entry[0].Description,
		}
		chartList = append(chartList, chart)
	}

	// 指定仓库的Chart信息
	logger.Debugf("%s", chartList)
	return chartList, nil
}
func searchAll(repoName, chartName string) ([]*ChartListResponse, error) {
	settings := cli.New()

	path := fmt.Sprintf("%s/%s-index.yaml", settings.RepositoryCache, repoName)
	// 加载 xxx-index.yaml 文件
	indexFile, err := repo.LoadIndexFile(path)
	if err != nil {
		return nil, fmt.Errorf("仓库 %s 不存在", repoName)
	}

	var chartList []*ChartListResponse

	// 遍历指定仓库的 Chart 信息
	for _, entry := range indexFile.Entries[chartName] {
		// 将每个 Chart 的主要信息提取出来
		chart := &ChartListResponse{
			ChartName:    entry.Name,
			ChartVersion: entry.Version,
			AppVersion:   entry.AppVersion,
			Description:  entry.Description,
		}
		chartList = append(chartList, chart)
	}

	// 指定仓库的Chart信息
	logger.Debugf("%s", chartList)
	return chartList, nil
}
func installChart(deployRequest *DeployRequest) error {
	settings := cli.New()

	actionConfig := new(action.Configuration)
	if err := actionConfig.Init(settings.RESTClientGetter(), deployRequest.Namespace, os.Getenv("HELM_DRIVER"), logger.Debugf); err != nil {
		return fmt.Errorf("初始化 action 失败\n%s", err)
	}

	install := action.NewInstall(actionConfig)
	install.RepoURL = deployRequest.RepoURL
	install.Version = deployRequest.ChartVersion
	install.Timeout = 30e9
	install.CreateNamespace = true
	install.Wait = true
	// kubernetes 中的配置
	install.Namespace = deployRequest.Namespace
	install.ReleaseName = deployRequest.ReleaseName

	chartRequested, err := install.ChartPathOptions.LocateChart(deployRequest.ChartName, settings)
	if err != nil {
		return fmt.Errorf("下载失败\n%s", err)
	}

	chart, err := loader.Load(chartRequested)
	if err != nil {
		return fmt.Errorf("加载失败\n%s", err)
	}

	_, err = install.Run(chart, nil)
	if err != nil {
		return fmt.Errorf("执行失败\n%s", err)
	}

	return nil
}
func uninstallChart(namespace, releaseName string) error {
	settings := cli.New()

	actionConfig := new(action.Configuration)
	if err := actionConfig.Init(settings.RESTClientGetter(), namespace, os.Getenv("HELM_DRIVER"), logger.Debugf); err != nil {
		return fmt.Errorf("初始化 action 失败\n%s", err)
	}

	uninstall := action.NewUninstall(actionConfig)
	uninstall.Timeout = 30e9 // 设置超时时间300秒
	uninstall.KeepHistory = false

	resp, err := uninstall.Run(releaseName)
	if err != nil {
		return fmt.Errorf("卸载失败\n%s", err)
	}

	logger.Infof("%s 成功卸载\n", resp.Release.Name)
	return nil
}
